package com.xiaoxi.exam.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

@Slf4j
public class HttpsUtils {

  private static final String HTTP = "http";
  private static final String HTTPS = "https";
  private static SSLConnectionSocketFactory sslsf = null;
  private static PoolingHttpClientConnectionManager cm = null;
  private static SSLContextBuilder builder = null;

  static {
    try {
      builder = new SSLContextBuilder();
      // 全部信任 不做身份鉴定
      builder.loadTrustMaterial(null, (TrustStrategy) (x509Certificates, s) -> true);
      sslsf = new SSLConnectionSocketFactory(builder.build(),
          new String[]{"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2"}, null,
          NoopHostnameVerifier.INSTANCE);
      Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
          .register(HTTP, new PlainConnectionSocketFactory())
          .register(HTTPS, sslsf)
          .build();
      cm = new PoolingHttpClientConnectionManager(registry);
      cm.setMaxTotal(200);//max connection
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static HttpResponse get(String preurl, Map<String, String> header,
      Map<String, String> param) throws Exception {
    CloseableHttpClient httpClient = null;
    try {
      httpClient = getHttpClient();
      String paramsStr = null;
      // 设置请求参数
      if (MapUtils.isNotEmpty(param)) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : param.entrySet()) {
          //给参数赋值
          formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        paramsStr = EntityUtils.toString(new UrlEncodedFormEntity(formparams, Consts.UTF_8));
      }
      String realUrl = Objects.isNull(paramsStr) ? preurl : preurl + "?" + paramsStr;
      HttpGet httpGet = new HttpGet(realUrl);
      // 设置头信息
      if (MapUtils.isNotEmpty(header)) {
        for (Map.Entry<String, String> entry : header.entrySet()) {
          httpGet.addHeader(entry.getKey(), entry.getValue());
        }
      }
      return httpClient.execute(httpGet);
    } finally {
      if (httpClient != null) {
        httpClient.close();
      }
    }
  }

  private static CloseableHttpClient getHttpClient() {
    return HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm)
        .setConnectionManagerShared(true).disableAutomaticRetries()
        .setRedirectStrategy(new LaxRedirectStrategy()).build();
  }
}
